using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Resources;
using System.Globalization;
using System.Collections.Specialized; 
using System.Runtime.InteropServices;

namespace commonV2.forms
{
    public partial class baseForm : Form
	{
    	public baseForm()
		{
            try
            {
                InitializeComponent();
                myErrorNotifier.BlinkRate = 25;
                this.StartPosition = FormStartPosition.CenterScreen;
                this.AutoScaleMode = AutoScaleMode.None;
                this.Font = new System.Drawing.Font("Microsoft Sans Serif", 10);
                //this.FormBorderStyle = (Settings.sysDebugMode ? FormBorderStyle.Sizable : FormBorderStyle.FixedSingle); 
            }
            catch (Exception er)
            {
                ErrorHandler(this, er);
            }
        }

        #region protected
        private reports.reportViewerForm _reportViewer = null;
        protected reports.reportViewerForm myReportViewer
        {
            get
            {
                if (_reportViewer == null || _reportViewer.IsDisposed) _reportViewer = new reports.reportViewerForm();
                return _reportViewer;
            }
            set { _reportViewer = value; }
        }

        protected bool fFormClosing = false;

        protected SaveFileDialog saveFileDialog = new SaveFileDialog();
        protected void ExportData(DataTable dataTbl)
        {
            ExportData(dataTbl, ExportLibs.Format.Excel, null, null);
        }
        protected void ExportData(DataTable dataTbl, ExportLibs.Format outputFormat, string[] columnList, string[] headerList)
        {
            switch (outputFormat)
            {
                case ExportLibs.Format.Excel:
                    DialogLibs.SetFileDialogEXCEL(this.saveFileDialog);
                    break;
                case ExportLibs.Format.CSV:
                    DialogLibs.SetFileDialogCSV(this.saveFileDialog);
                    break;
                case ExportLibs.Format.XML:
                    DialogLibs.SetFileDialogHTML(this.saveFileDialog);
                    break;
                default: return;
            }
            if (this.saveFileDialog.ShowDialog() != DialogResult.OK) return;

            // Get the datatable to export			
            bool retVal = ExportLibs.ExportToExcel(dataTbl, this.saveFileDialog.FileName, columnList, headerList);
            if (retVal)
                SysLibs.ShowMessage(String.Format(language.GetString("dataSavedTo"), this.saveFileDialog.FileName));
            else SysLibs.ShowMessage(String.Format(language.GetString("errorOccured"), errorHandler.lastException.Message));
        }

        protected void ShowReccount(int reccount)
        {
            ShowReccount("[" + reccount.ToString("###,###,###,###") + "]");
        }
        protected void ShowMessage(string msg)
        {
            ShowMessage(msg, "");
        }
        protected void ShowMessage(string msg, string statusMsg)
        {
            this.messageLbl.Text = msg;
            this.statusLbl.Text = statusMsg;
        }
        protected void ShowStatus(string statusMsg)
        {
            this.statusLbl.Text = statusMsg;
        }

        #endregion

        #region public
        private ColorTypes _colorType = ColorTypes.Form;
        private ColorTypes myColorType
        {
            set
            {
                _colorType = value;
                ApplyTheme();
            }
            get
            {
                return _colorType;
            }
        }
        protected virtual void ApplyTheme()
        {
            if (Settings.sysIsDesignMode) return;
            ColorSet cs = ThemeLibs.GetColorSet(this.myColorType);
            if (cs != null)
            {
                this.BackColor = cs.BackColor;
                this.ForeColor = cs.ForeColor;
            }
        }
        protected void ApplyTheme(ColorTypes colorType)
        {
            if (Settings.sysIsDesignMode) return;
            ColorSet cs = ThemeLibs.GetColorSet(colorType);
            if (cs != null)
            {
                this.BackColor = cs.BackColor;
                this.ForeColor = cs.ForeColor;
            }
        }

        public bool isLoaded = false;

        private bool _isLockEdit = true;
        public bool isLockEdit
        {
            get { return this._isLockEdit; }
            set
            {
                this._isLockEdit = value;
            }
        }

        public myTypes.Permissions _myPermission = null;
        public myTypes.Permissions myPermission
        {
            get
            {
                try
                {
                    if (_myPermission == null || _myPermission.IsNotSet())
                    {
                        _myPermission = GetFormPermission();
                    }
                    return _myPermission;
                }
                catch (Exception er)
                {
                    ErrorHandler(this, er);
                }
                return new myTypes.Permissions();
            }
            set
            {
                try
                {
                    _myPermission = value;
                }
                catch (Exception er)
                {
                    ErrorHandler(this, er);
                }
            }
        }

        public Image myStatusImage
        {
            get { return this.statusImg.myImage; }
            set { this.statusImg.myImage = value; }
        }
        public bool myStatusImageVisibled
        {
            get { return statusImg.Visible; }
            set { statusImg.Visible = value; }
        }
        public bool myStatusImageEnabled
        {
            get { return statusImg.Enabled; }
            set { statusImg.Enabled = value; }
        }
        public string myStatusToolTipText
        {
            get { return statusImg.ToolTipText; }
            set { statusImg.ToolTipText = value; }
        }

        public delegate void myOnError(object sender, Exception er);
        public delegate void myOnStatusImagClickEvent(object sender, EventArgs e);

        public event myOnError myOnErrorEvent = null;
        public event myOnStatusImagClickEvent myOnStatusImgClick = null;
        public event commonV2.controls.baseReportViewer.onPrinted myOnPrinted
        {
            add
            {
                myReportViewer.myOnPrinted += value;
            }

            remove
            {
                myReportViewer.myOnPrinted -= value;
            }
        }

        public void NotifyError(Control lbl) { myErrorNotifier.SetError(lbl, lbl.Text); }
        public void NotifyError(Control lbl, string text)
        {
            string tmp = myErrorNotifier.GetError(lbl);
            tmp += (tmp.Trim() == "" ? "" : Consts.constCRLF) + text;
            myErrorNotifier.SetError(lbl, text);
        }
        public void ClearNotifyError()
        {
            myErrorNotifier.Clear();
        }
        public virtual void ResetReport()
        {
            myReportViewer.Close();
            myReportViewer = null;
        }

        public void ShowCurrorWait()
        {
            SysLibs.ShowCurrorWait();
        }
        public void ShowCurrorDefault()
        {
            SysLibs.ShowCurrorDefault();
        }

        public void SetReport(CrystalDecisions.CrystalReports.Engine.ReportClass myReport)
        {
            // Unknown bug: after showing the reposrt, all later showing will produce an error.
            // Reset the viwer will help to kill the bug
            //ResetReport();
            myReportViewer.SetReport(myReport);
        }
        public void SetReport(object[] paraValue, string prefix)
        {
            myReportViewer.SetReport(paraValue, prefix);
        }
        public void SetReport(object paraValue, string paraName)
        {
            myReportViewer.SetReport(paraValue, paraName);
        }

        public void ShowReport()
        {
            myReportViewer.ShowReport(true);
        }
        public virtual void ShowReport(bool preview)
        {
            myReportViewer.ShowReport(preview);
        }

        public void SetTitle(string title, string caption)
        {
            TitleLbl.Text = title;
            this.Text = caption;
        }
        public void SetStatusWidth(int w)
        {
            this.statusLbl.Size = new Size(w, this.statusLbl.Height);
        }

        public void LockEditData(bool lockState)
        {
            try
            {
                this.isLockEdit = lockState;
                LockEdit();
            }
            catch(Exception er)
            {
                //ErrorHandler(this, er);
            }
        }

        #endregion

        #region virtual
        public virtual void WriteLog(string text)
        {
            string fileName = this.Name.Trim() + ".log";
            SysLog.WriteLog(text, fileName);
        }

        public virtual void Reset()
        {
            this.myPermission = null;
        }
        protected virtual void ErrorHandler(object sender, Exception er)
        {
            this.ShowMessage(er.Message);
            if (myOnErrorEvent!=null) myOnErrorEvent(sender,er);
            return;
        }
        protected virtual void QuitApplication()
        {
            SysLibs.ExitApplication();
            if (Settings.sysIsDesignMode == false) this.Close();
        }
        protected virtual bool BeforeLoadForm() { return true; }
        protected virtual bool BeforeCloseForm() { return true; }
        public virtual void SetLanguage() { }
        public virtual void LockEdit()
        {
            //this.isLockEdit = (this.isLockEdit || this.myPermission.Edit == false);
        }

        public virtual void Print(bool preview)
        {
            SysLibs.ShowErrorMessage(language.GetString("functionNotDone"));
        }
        protected virtual void Export() { }

        protected virtual bool isNewRow(DataRow dataRow)
        {
            return dataRow.RowState == DataRowState.Detached || dataRow.RowState == DataRowState.Added;
        }

        protected virtual bool LoadConfigure() { return true; }
        protected virtual bool SaveConfigure() { return true; }
        /// <summary>
        /// Get permission of current user
        /// </summary>

        protected virtual myTypes.Permissions GetFormPermission()
        {
            return new myTypes.Permissions();
        }
        protected virtual string[] SaveEditData() { return null; }
        protected virtual void RestoreEditData(string[] saveData) { }
        protected virtual void ShowReccount(string msg)
        {
            this.countLbl.Text = msg;
            this.myStatusStrip.Refresh();
        }
        #endregion

        #region override
        public override void Refresh()
        {
            ApplyTheme();
            base.Refresh();
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            ApplyTheme();
        }


        //Make Enter key works as Tabkey
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (this.ActiveControl != null)
            {
                string name = this.ActiveControl.GetType().Name.ToUpper().Trim();
                //Make ENTER key work as TAB key for all controls except BUTTON
                if ((Settings.sysEnterSameAsTabKey && (msg.WParam.ToInt32() == (int)Keys.Enter) &&
                    (this.ActiveControl != null) &&
                    (name != "BUTTON") && (!name.StartsWith("RICHTEXT"))))
                {
                    SendKeys.Send("{Tab}");
                    return true;
                }
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
        #endregion

        #region event handler
        private void myStatusStrip_MouseHover(object sender, EventArgs e)
        {
            messageLbl.ToolTipText = this.messageLbl.Text.ToString();
        }

        private void baseForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (!BeforeCloseForm())
                {
                    e.Cancel = true;
                    return;
                }
                SaveConfigure();
                if (myReportViewer != null && !myReportViewer.IsDisposed) myReportViewer.Dispose(); 
                fFormClosing = true;
            }
            catch (Exception er)
            {
                ErrorHandler(this, er);
            }
        }

        private void baseForm_Load(object sender, EventArgs e)
        {
            try
            {
                if (!BeforeLoadForm())
                {
                    QuitApplication();
                    return;
                }
                LoadConfigure();
                this.isLoaded = true;
                SetLanguage();
            }
            catch (Exception er)
            {
                ErrorHandler(this, er);
            }
        }

        private void statusImg_Click(object sender, EventArgs e)
        {
            try
            {
                if (myOnStatusImgClick != null) myOnStatusImgClick(sender, e);
            }
            catch (Exception er)
            {
                ErrorHandler(this, er);
            }
        }
        #endregion
    }
}